package com.kuangjia.student_ems.service.impl;

import com.kuangjia.student_ems.dto.PositionDTO;
import com.kuangjia.student_ems.dto.request.PositionRequest;
import com.kuangjia.student_ems.entity.Department;
import com.kuangjia.student_ems.entity.Position;
import com.kuangjia.student_ems.exception.BusinessException;
import com.kuangjia.student_ems.exception.ResourceNotFoundException;
import com.kuangjia.student_ems.repository.DepartmentRepository;
import com.kuangjia.student_ems.repository.PositionRepository;
import com.kuangjia.student_ems.repository.PositionMapper;
import com.kuangjia.student_ems.repository.UserRepository;
import com.kuangjia.student_ems.service.PositionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;

import java.util.List;
import java.util.stream.Collectors;

@Service
public class PositionServiceImpl implements PositionService {
    
    private final PositionRepository positionRepository;
    private final DepartmentRepository departmentRepository;
    private final UserRepository userRepository;
    
    @Autowired
    private PositionMapper positionMapper;
    
    @Autowired
    public PositionServiceImpl(PositionRepository positionRepository, DepartmentRepository departmentRepository, UserRepository userRepository) {
        this.positionRepository = positionRepository;
        this.departmentRepository = departmentRepository;
        this.userRepository = userRepository;
    }
    
    @Override
    @Transactional
    public PositionDTO createPosition(PositionRequest request) {
        // 检查部门是否存在
        Department department = departmentRepository.findById(request.getDepartmentId())
                .orElseThrow(() -> new ResourceNotFoundException("部门", "id", request.getDepartmentId()));
        
        // 检查同一部门下岗位名称是否重复
        if (positionRepository.existsByNameAndDepartmentId(request.getName(), request.getDepartmentId())) {
            throw new BusinessException("该部门下已存在同名岗位");
        }
        
        Position position = new Position();
        position.setName(request.getName());
        position.setDepartment(department);
        position.setDescription(request.getDescription());
        position.setStatus(request.getStatus());
        position.setSchemeId(request.getSchemeId());
        
        Position savedPosition = positionRepository.save(position);
        return convertToDTO(savedPosition);
    }
    
    @Override
    @Transactional
    public PositionDTO updatePosition(Long id, PositionRequest request) {
        Position position = positionRepository.findById(id)
                .orElseThrow(() -> new ResourceNotFoundException("岗位", "id", id));
        
        // 检查部门是否存在
        Department department = departmentRepository.findById(request.getDepartmentId())
                .orElseThrow(() -> new ResourceNotFoundException("部门", "id", request.getDepartmentId()));
        
        // 检查同一部门下岗位名称是否重复
        if (positionRepository.existsByNameAndDepartmentIdAndIdNot(request.getName(), request.getDepartmentId(), id)) {
            throw new BusinessException("该部门下已存在同名岗位");
        }
        
        position.setName(request.getName());
        position.setDepartment(department);
        position.setDescription(request.getDescription());
        position.setStatus(request.getStatus());
        position.setSchemeId(request.getSchemeId());
        
        Position updatedPosition = positionRepository.save(position);
        return convertToDTO(updatedPosition);
    }
    
    @Override
    @Transactional
    public void deletePosition(Long id) {
        Position position = positionRepository.findById(id)
                .orElseThrow(() -> new ResourceNotFoundException("岗位", "id", id));
        
        // 检查是否有员工使用该岗位
        if (userRepository.existsByPositionId(id)) {
            throw new BusinessException("该岗位下存在员工，无法删除");
        }
        
        positionRepository.delete(position);
    }
    
    @Override
    public PositionDTO getPositionById(Long id) {
        Position position = positionRepository.findById(id)
                .orElseThrow(() -> new ResourceNotFoundException("岗位", "id", id));
        return convertToDTO(position);
    }
    
    @Override
    public List<PositionDTO> getAllPositions() {
        List<Position> positions = positionRepository.findAll();
        return positions.stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());
    }
    
    @Override
    public List<PositionDTO> getPositionsByDepartment(Long departmentId) {
        // 检查部门是否存在
        if (!departmentRepository.existsById(departmentId)) {
            throw new ResourceNotFoundException("部门", "id", departmentId);
        }
        
        List<Position> positions = positionRepository.findByDepartmentId(departmentId);
        return positions.stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());
    }
    
    @Override
    public List<PositionDTO> getActivePositions() {
        List<Position> positions = positionRepository.findByStatus(true);
        return positions.stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());
    }
    
    @Override
    public List<PositionDTO> getActivePositionsByDepartment(Long departmentId) {
        // 检查部门是否存在
        if (!departmentRepository.existsById(departmentId)) {
            throw new ResourceNotFoundException("部门", "id", departmentId);
        }
        
        List<Position> positions = positionRepository.findByDepartmentIdAndStatus(departmentId, true);
        return positions.stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());
    }
    
    @Override
    @Transactional
    public PositionDTO togglePositionStatus(Long id) {
        Position position = positionRepository.findById(id)
                .orElseThrow(() -> new ResourceNotFoundException("岗位", "id", id));
        
        // 如果要禁用岗位，检查是否有员工使用该岗位
        if (position.getStatus() && userRepository.existsByPositionId(id)) {
            throw new BusinessException("该岗位下存在员工，无法禁用");
        }
        
        position.setStatus(!position.getStatus());
        Position updatedPosition = positionRepository.save(position);
        return convertToDTO(updatedPosition);
    }
    
    @Override
    public List<PositionDTO> searchPositions(String keyword) {
        if (keyword == null || keyword.trim().isEmpty()) {
            return getAllPositions();
        }
        
        String searchTerm = "%" + keyword.toLowerCase() + "%";
        List<Position> positions = positionRepository.searchPositions(searchTerm);
        return positions.stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());
    }
    
    @Override
    public IPage<PositionDTO> getPositionPage(Page<Position> page, String keyword) {
        try {
            QueryWrapper<Position> wrapper = new QueryWrapper<>();
            if (keyword != null && !keyword.isEmpty()) {
                wrapper.lambda().like(Position::getName, keyword)
                    .or().like(Position::getDescription, keyword);
            }
            wrapper.lambda().orderByAsc(Position::getId);
            IPage<Position> positionPage = positionMapper.selectPage(page, wrapper);
            IPage<PositionDTO> dtoPage = positionPage.convert(this::convertToDTO);
            return dtoPage;
        } catch (Exception e) {
            System.err.println("岗位分页查询异常: " + e.getMessage());
            e.printStackTrace();
            throw e;
        }
    }
    
    private PositionDTO convertToDTO(Position position) {
        PositionDTO dto = new PositionDTO();
        dto.setId(position.getId());
        dto.setName(position.getName());
        
        // 设置部门信息
        if (position.getDepartmentId() != null) {
            dto.setDepartmentId(position.getDepartmentId());
            // 如果有关联的department对象，直接使用
            if (position.getDepartment() != null) {
                dto.setDepartmentName(position.getDepartment().getName());
            } else {
                // 否则通过departmentId查询部门名称
                try {
                    Department department = departmentRepository.findById(position.getDepartmentId()).orElse(null);
                    if (department != null) {
                        dto.setDepartmentName(department.getName());
                    } else {
                        dto.setDepartmentName("未知部门");
                    }
                } catch (Exception e) {
                    dto.setDepartmentName("未知部门");
                }
            }
        }
        
        dto.setDescription(position.getDescription());
        dto.setStatus(position.getStatus());
        dto.setCreateTime(position.getCreateTime());
        dto.setUpdateTime(position.getUpdateTime());
        
        return dto;
    }
} 